#include "ET++.ph"
#ifdef __GNUG__
#pragma implementation
#endif

#include "EtProgEnv.h"

#include "Class.h"
#include "OrdColl.h"
#include "Application.h"
#include "InspClickDialog.h"
#include "WindowSystem.h"
#include "PathLookup.h"

#include "EtPeManager.h"
#include "SrcBrowser.h"
#include "ClassTree.h"
#include "OStruBrowser.h"
#include "Inspector.h"

extern void ObjectViewOnEntry(ProgEnv *pe);

//---- EtProgEnv ---------------------------------------------------------------

NewMetaImpl(EtProgEnv, ProgEnv, (TP(objViewPolicies), TP(pe)));

EtProgEnv::EtProgEnv()
{
}

void EtProgEnv::InitNew()
{
	WindowSystem::WSInit();
	dialog= 0;
	objViewPolicies= new OrdCollection();
	ObjectViewOnEntry(this);
}

EtProgEnv::~EtProgEnv()
{
	objViewPolicies->FreeAll();
	SafeDelete(objViewPolicies);
	Object *path= EtPeManager::Universe();
	if (path)
		path->FreeAll();
	SafeDelete(path);
	SafeDelete(dialog);
}

void EtProgEnv::Start()
{
	MakeEtPeManager();
}

void EtProgEnv::EditSourceOf(Class *cp, bool decl, int at)
{
	PeSourceBrowser::ShowClass(MakeEtPeManager(), cp, decl, at);
}

void EtProgEnv::ShowInHierarchy(Class *cp)
{
	PeHierarchyBrowser::ShowClass(MakeEtPeManager(), cp);
}

void EtProgEnv::InspectObject(Object *op, bool block)
{
	PeInspector::ShowObject(MakeEtPeManager(), op, block);
}

void EtProgEnv::AddObjectViewPolicy(ObjectViewPolicy *avh)
{
	objViewPolicies->Add(avh);
}

char *EtProgEnv::HasObjectView(Class *cl, void *addr, Object *op)
{
	Iter prev(objViewPolicies->MakeReversedIterator());
	ObjectViewPolicy *avh;
	char *name;
	while (avh= (ObjectViewPolicy *)prev())
		if (name= avh->ViewName(cl, addr, op))
			return name;
	return 0;
}

void EtProgEnv::ShowObjectView(Class *cl, void *addr, Object *op, Object *insp)
{
	Iter prev(objViewPolicies->MakeReversedIterator());
	ObjectViewPolicy *avh;
	while (avh= (ObjectViewPolicy*)prev())
		if (avh->ShowView(cl, addr, op, insp))
			break;
}

void EtProgEnv::ShowInObjStruBrowser(Object *op)
{
	PeObjectBrowser::ShowObject(MakeEtPeManager(), op);
}

EtPeManager *EtProgEnv::MakeEtPeManager()
{
	if (gEtPeManager == 0) {
		pe= gEtPeManager= new EtPeManager;
		if (gApplication)
			gApplication->AddManager(gEtPeManager);
		gEtPeManager->Open();
	} else
		gEtPeManager->Show();
	return gEtPeManager;
}

PathLookup *EtProgEnv::Universe()
{
	return EtPeManager::Universe();
}

bool EtProgEnv::FileOfClass(Class *cl, char *fname, bool decl)
{
	return EtPeManager::FileOfClass(cl, fname, decl);
}

void EtProgEnv::InspectClick(VObject *vop)
{
	Object *op;
	if (dialog == 0)
		dialog= new PeInspectClickDialog();
	switch (dialog->ShowInWindow(vop)) {
	case cIdOk:
		op= dialog->GetObject();
		if (op)
			op->Inspect();
		break;
	case cIdIClickEdit:
		op= dialog->GetObject();
		if (op)
			op->EditSource(TRUE);
		break;
	case cIdIClickTree:
		op= dialog->GetObject();
		if (op)
			ShowInHierarchy(op->IsA());
		break;
	}
}

void EtProgEnv::Use()
{
}

